/**
* Company: QuantaNetwork BeiJing Ltd
* Author : 张彦龙
* DateTime: Nov 26, 2008  5:28:05 PM
*/
package com.quantanetwork.esm.port;

import java.net.DatagramPacket;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.logging.Logger;

public class QuantaPortTools extends UdpSocket implements Callable<Result>
{
	/**
	 * 
	 */
	private static final long serialVersionUID = -6858577071237278629L;
	public static Logger logger = Logger.getLogger(QuantaPortTools.class.getName());
	private String server;
	private int startPort;
	private int endPort;
	private int timeOut;
	private String message = "help^M^J";
	public static final int TCP = 0;
	public static final int UDP = 1;
	private String response = "";
	private int type = 0;
	private boolean tcp;

	public QuantaPortTools()
	{
		// TODO Auto-generated constructor stub
	}

	public String getServer()
	{
		return server;
	}

	public int getStartPort()
	{
		return startPort;
	}

	public int getEndPort()
	{
		return endPort;
	}

	public int getTimeOut()
	{
		return timeOut;
	}

	public String getMessage()
	{
		return message;
	}

	public String getResponse()
	{
		return response;
	}

	public int getType()
	{
		return type;
	}

	public boolean isTcp()
	{
		return tcp;
	}

	public QuantaPortTools(String server, int startPort, int endPort, int timeOut, int type)
	{
		super();
		this.server = server;
		this.startPort = startPort;
		this.endPort = endPort;
		this.timeOut = timeOut;
		this.type = type;
	}

	public QuantaPortTools(String server, int startPort, int endPort, int timeOut, String message, int type)
	{
		super();
		this.server = server;
		this.startPort = startPort;
		this.endPort = endPort;
		this.timeOut = timeOut;
		this.message = message;
		this.type = type;
	}

	public byte[] send(DatagramPacket dataPacket) throws SocketException
	{
		byte[] rtnPdu = null;
		openUdpSocket();
		try
		{
			getDatagramSocket().send(dataPacket);
			rtnPdu = read();
		}
		catch (Exception ex)
		{
			//logger.severe("Send DatagramPacket error[" + ex.getLocalizedMessage() + "],Dest Address[" + dataPacket.getAddress().getHostAddress() + "],Dest Port[" + dataPacket.getPort() + "]");
		}
		closeUdpSocket();
		return rtnPdu;
	}

	public byte[] read() throws SocketException
	{
		byte[] data = null;
		DatagramPacket datagramPacket = new DatagramPacket(new byte[getDatagramPacketSize()], getDatagramPacketSize());
		openUdpSocket();
		try
		{
			getDatagramSocket().receive(datagramPacket);
			int dataLen = datagramPacket.getLength();
			if (dataLen > 0)
			{
				data = datagramPacket.getData();
			}
		}
		catch (SocketTimeoutException ex)
		{
		}
		catch (Exception ex)
		{
			//logger.severe("Read Snmp Packet Error[" + ex.getLocalizedMessage() + "]");
		}
		closeUdpSocket();
		return data;
	}

	@Override
	public Result call() throws Exception
	{
		long start = System.currentTimeMillis();
		Result result = new Result();
		List<Portinfo> list = new ArrayList<Portinfo>();
		for (int i = startPort; i < endPort; i++)
		{
			boolean error = false;
			String response = "";
			if (type == TCP)
			{
				tcp = true;
			}
			else
			{
				tcp = false;
			}
			if (tcp)
			{
				Socket socket = null;
				try
				{
					socket = new Socket();
					socket.connect(new InetSocketAddress(server, i), 2000);
				}
				catch (Exception e)
				{
					response += "; " + e.toString();
					error = true;
				}
				if (!error)
				{
					Portinfo bean = new Portinfo(server, i, "TCP");
					list.add(bean);
				}
				if (socket != null)
				{
					try
					{
						socket.close();
					}
					catch (Exception e)
					{
						logger.info(server + "上" + i + "TCP 连接异常");
					}
				}
			}
			else
			{
				try
				{
					byte[] data = null;
					int iLen = message.getBytes().length;
					InetSocketAddress isa = new InetSocketAddress(server, i);
					DatagramPacket packet = new DatagramPacket(message.getBytes(), 0, iLen, isa);
					data = send(packet);
					if (data.length > 0)
					{
						Portinfo bean = new Portinfo(server, i, "UDP");
						bean.setResponse(new String(data, data.length));
						list.add(bean);
					}
				}
				catch (Exception ex)
				{
					//logger.severe("Send PDU error[" + ex.getLocalizedMessage() + "]");
				}
			}
		}
		result.setList(list);
		result.setInfo("Port From:" + startPort + "  TO:" + endPort + "Scan Complete");
		result.setTime(System.currentTimeMillis() - start);
		return result;
	}

	public void setServer(String server)
	{
		this.server = server;
	}

	public void setStartPort(int startPort)
	{
		this.startPort = startPort;
	}

	public void setEndPort(int endPort)
	{
		this.endPort = endPort;
	}

	public void setTimeOut(int timeOut)
	{
		this.timeOut = timeOut;
	}

	public void setMessage(String message)
	{
		this.message = message;
	}

	public void setResponse(String response)
	{
		this.response = response;
	}

	public void setType(int type)
	{
		this.type = type;
	}

	public void setTcp(boolean tcp)
	{
		this.tcp = tcp;
	}
}
